/*
 * Copyright (C) 2015 yixun All Rights Reserved.
 *
 * AreaServiceImpl.java
 */
package com.yixun.qfbao.api.service.impl;

import com.yixun.qfbao.api.service.*;
import com.yixun.qfbao.apidto.*;
import com.yixun.qfbao.config.M2ApiConfig;
import com.yixun.qfbao.constant.StringConstant;
import com.yixun.qfbao.dao.AdviserChangeDao;
import com.yixun.qfbao.model.Company;
import com.yixun.qfbao.model.EstateAdviser;
import com.yixun.qfbao.model.PartnerInfo;
import com.yixun.qfbao.model.dto.CompanyDto;
import com.yixun.qfbao.model.enums.*;
import com.yixun.qfbao.service.CompanyService;
import com.yixun.qfbao.service.PartnerInfoService;
import com.yixun.qfbao.util.DateStyle;
import com.yixun.qfbao.util.DateUtils;
import com.yixun.qfbao.util.exception.TServerException;
import com.yixun.qfbao.xf.model.CustomerPremises;
import com.yixun.qfbao.xf.model.Premises;
import com.yixun.qfbao.xf.model.dto.CustomerPremisesDto;
import com.yixun.qfbao.xf.model.dto.FollowUpListDto;
import com.yixun.qfbao.xf.model.enums.*;
import com.yixun.qfbao.xf.service.CustomerPremisesService;
import com.yixun.qfbao.xf.service.FollowUpListService;
import com.yixun.qfbao.xf.service.PremisesService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * [文件名称]<br>
 * CPReportServiceImpl.java<br>
 * <br>
 * [文件描述]<br>
 * 报备相关<br>
 * <br>
 *
 * @author JHSong
 * @version 1.00
 */
@Service
public class AuditReportServiceImpl implements AuditReportService {

    private Logger logger = LoggerFactory.getLogger(AuditReportServiceImpl.class);

    @Autowired
    M2ApiConfig m2ApiConfig;
    @Autowired
    private CPService cpService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private CPReportService cpReportService;
    @Autowired
    private PremisesService premisesService;
    @Autowired
    private PartnerInfoService partnerInfoService;
    @Autowired
    private ReportCommonService reportCommonService;
    @Autowired
    private FollowUpListService followUpListService;
    @Autowired
    private WeAppMessageService weAppMessageService;
    @Autowired
    private AdviserChangeDao adviserChangeDao;
    @Autowired
    private CustomerPremisesService customerPremisesService;
    @Autowired
    private EstateAdviserService estateAdviserService;
    @Autowired
    private WHReportService whReportService;

    @Override
    @Transactional
    public AuditCPResDto auditCP(AuditCPReqDto reqDto, String agencyAccessToken, String assistantAccessToken) {
        AuditCPResDto resDto = new AuditCPResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        CustomerPremises customerPremises = customerPremisesService.selectByIdForLock(Long.valueOf(reqDto.getId()));

        if (null == customerPremises) {
            throw new TServerException("报备记录无效,无法进行审核操作！");
        }
        if (customerPremises.getCustomerStatus().equals(reqDto.getCustomerStatus())) {
            throw new TServerException("操作重复，请刷新之后进行操作！");
        }

        // 已到访,校验是否存在有效的手机号报备记录
        Premises premises = premisesService.selectSimpleById(customerPremises.getPremisesId());
        if (CustomerStatusEnum.not_visited.getNo().equals(reqDto.getCustomerStatus())
                || CustomerStatusEnum.has_visited.getNo().equals(reqDto.getCustomerStatus())) {
            if (customerPremises.getMobile().indexOf(StringConstant.THREE_STAR) < 0) {
                boolean flag = customerPremisesService.checkVisitRepeat(Long.valueOf(reqDto.getId()), premises, customerPremises.getMobile());
                if (flag) {
                    resDto.setResultMsg("客户已到访该楼盘,无法重复审核!");
                    return resDto;
                }
            }
        }

        checkCPAuditStatus(customerPremises.getCustomerStatus(), reqDto.getCustomerStatus());
        String oldConfirmStatus = customerPremises.getConfirmStatus();
        String newConfirmStatus = customerPremises.getConfirmStatus();
        String oldCustomerStatus = customerPremises.getCustomerStatus();
        String newCustomerStatus = reqDto.getCustomerStatus();

        Date nowTime = Calendar.getInstance().getTime();
        CustomerPremisesDto cpDto = new CustomerPremisesDto();
        BeanUtils.copyProperties(customerPremises, cpDto);

        // 设置失败状态
        if (CustomerStatusEnum.no_valid.getNo().equals(newCustomerStatus)) {
            if (CustomerStatusEnum.normal == CustomerStatusEnum.getByNo(oldCustomerStatus)) {
                //报备审核无效
                cpDto.setDisableType(DisableTypeEnum.report_invalid.getNo());
            } else {
                //到访审核无效
                cpDto.setDisableType(DisableTypeEnum.visit_invalid.getNo());
            }
        } else {
            // 隐号报备审核、到访审核校验是否需要补全手机号
            if (customerPremises.getMobile().indexOf(StringConstant.THREE_STAR) >= 0) {
                Boolean flag = cpService.checkCompletePhone(premises, customerPremises, customerPremises.getConfirmStatus());
                // 非设置无效操作,校验隐号补全
                if (!flag.booleanValue()) {
                    resDto.setResultMsg("请先补全号码再进行审核操作!");
                    return resDto;
                }
            }
            if (CustomerStatusEnum.has_visited.getNo().equals(newCustomerStatus)) {
                // 判断当前时间是否已过最短到访时间
                String specialTimeType = premises.getSpecialTimeType();
                if(!TimeUnitTypeEnum.NONE.getNo().equals(specialTimeType)){
                    Date visitPastTime = customerPremises.getVisitPastTime();
                    if (Objects.isNull(visitPastTime)) {
                        // 到访审核最低时间不存在,通过报备及楼盘设置重新计算
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(customerPremises.getCreateTime());
                        if (StringUtils.isNotBlank(premises.getSpecialTime())) {
                            calendar.add(Calendar.MINUTE, Integer.valueOf(premises.getSpecialTime()));
                        }
                        visitPastTime = calendar.getTime();
                    }
                    if (visitPastTime.compareTo(Calendar.getInstance().getTime()) >= 0) {
                        resDto.setResultMsg("当前时间小于最短报备时间,无法审核到访!");
                        return resDto;
                    }
                }
                // 到访时间为页面实际填写的时间
                Date visitTime = reqDto.getCreateTime();
                if (Objects.nonNull(visitTime)) {
                    nowTime = visitTime;
                }
                cpDto.setVisitTime(nowTime);
                // 根据楼盘规则,设置保护时间
                String visitBaohuType = premises.getVisitBaohuType();
                String visitBaohu = premises.getVisitBaohu();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(nowTime);
                if (TimeUnitTypeEnum.DAY.getNo().equals(visitBaohuType)
                        || TimeUnitTypeEnum.HOUR.getNo().equals(visitBaohuType)
                        || TimeUnitTypeEnum.MINUT.getNo().equals(visitBaohuType)) {
                    calendar.add(Calendar.MINUTE, Integer.valueOf(visitBaohu));
                    cpDto.setVisitBaohuTime(calendar.getTime());
                } else if (TimeUnitTypeEnum.NONE.getNo().equals(visitBaohuType)) {
                    // 不需要保护,默认为当前时间
                    cpDto.setVisitBaohuTime(calendar.getTime());
                }
            }
        }

        if (CustomerStatusEnum.has_visited.getNo().equals(newCustomerStatus)) {
            cpDto.setVisitState("1");
        }
        cpDto.setCustomerStatus(newCustomerStatus);
        cpDto.setAdviserUuid(reqDto.getAdviserUuid());
        //更新数据
        if (customerPremisesService.update(cpDto) <= 0) {
            resDto.setResultMsg("更新审核数据失败!");
            return resDto;
        }
        if (CustomerStatusEnum.has_visited.getNo().equals(newCustomerStatus) && StringUtils.isNotBlank(reqDto.getAdviserUuid())) {
            adviserChangeDao.addAdviserChange(Arrays.asList(customerPremises), reqDto.getAdviserUuid(), reqDto.getUserId());
        }

        PartnerInfo pi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
        List<AffixDto> affixList = reqDto.getAffixList();
        String operFollowRemark = "【" + CustomerStatusEnum.getDescByNo(reqDto.getCustomerStatus()) + "】";
        if(Objects.nonNull(customerPremises.getReportPeriodTime()) && CustomerStatusEnum.not_visited.getNo().equals(newCustomerStatus)){
            //String dateStr = DateUtils.DateToString(customerPremises.getReportPeriodTime(), DateStyle.YYYY_MM_DD_HH_MM_SS);
            //operFollowRemark += "报备保护截止时间为"+dateStr+"，请尽快完成带看。";
        }
        operFollowRemark += reqDto.getRemark();

        Map<String, String> statusMap = new HashMap<>();
        statusMap.put("oldCustomerStatus", oldCustomerStatus);
        statusMap.put("newCustomerStatus", newCustomerStatus);
        statusMap.put("oldConfirmStatus", oldConfirmStatus);
        statusMap.put("newConfirmStatus", newConfirmStatus);
        // 添加跟进
        reportCommonService.setAuditFollow(pi, Long.valueOf(reqDto.getId()), statusMap, cpDto.getDisableType(), operFollowRemark, affixList, OperationTypeEnum.OPERATIONTYPE_3.getCode());

        resDto.setResult(ResultEnum.SUCCESS.getNo());
        resDto.setResultMsg("审核成功!");

        // 到访成功自动转客
        // 判断渠道商是否打通M2
        if (CustomerStatusEnum.has_visited.getNo().equals(reqDto.getCustomerStatus())) {
            long companyId = pi.getHigherid();
            String merchantCode = companyService.isDevBindM2(String.valueOf(companyId), CompanyTypeEnum.COMPANY_TYPE_VALUE_2.getCode());
            if (StringUtils.isNotBlank(merchantCode)) {
                if (StringUtils.isNotBlank(premises.getProjectCodeM2())) {
                    reportCommonService.customerToM2(customerPremises, m2ApiConfig.getM2RequestUrl(),merchantCode);
                }
            }
            // 发送到访短信
            reportCommonService.sendAuditCPSms(pi, customerPremises);
        }

        WxMsgCommonDto wxMsgCommonDto = new WxMsgCommonDto();
        wxMsgCommonDto.setDomain(reqDto.getDomain());
        wxMsgCommonDto.setCompanyUuid(reqDto.getCompanyUuid());
        wxMsgCommonDto.setRemark(reqDto.getRemark());
        reportCommonService.sendAuditWxMsg(customerPremises, statusMap, wxMsgCommonDto, agencyAccessToken, assistantAccessToken);

        /*
         * 同步V10报备审核信息
         * 判断是否为V10推过来的报备
         * 查看约看信息
         * 越看信息中有V10报备id
         */
        SyncReportStatusToV10Dto toV10Dto = new SyncReportStatusToV10Dto();
        toV10Dto.setReportId(customerPremises.getId());
        toV10Dto.setCompanyUuid(reqDto.getCompanyUuid());
        toV10Dto.setRemark(reqDto.getRemark());
        toV10Dto.setOperFollowRemark(operFollowRemark);
        toV10Dto.setReportPeriodTime(customerPremises.getReportPeriodTime() != null ? DateUtils.DateToString(customerPremises.getReportPeriodTime(), DateStyle.YYYY_MM_DD_HH_MM_SS) : null);
        //推送置业顾问
        if(StringUtils.isNotEmpty(reqDto.getAdviserUuid())){
            EstateAdviser entity = new EstateAdviser();
            entity.setAdviserUuid(reqDto.getAdviserUuid());
            EstateAdviser adviser =  estateAdviserService.selectOne(entity);
            if(adviser != null) {
                toV10Dto.setAdviserName(adviser.getName());
                toV10Dto.setAdviserPhone(adviser.getPhone());
            }
        }
        // 如果是已到访
        if(CustomerStatusEnum.has_visited.getNo().equals(cpDto.getCustomerStatus())){
            toV10Dto.setVisitTime(cpDto.getVisitTime() == null ? null : DateUtils.DateToString(cpDto.getVisitTime(), DateStyle.YYYY_MM_DD_HH_MM_SS));
        }
        reportCommonService.syncReportStatusToV10(OperationTypeEnum.OPERATIONTYPE_3.getCode(), toV10Dto, statusMap, affixList);
        return resDto;
    }

    @Override
    public ResetAuditResDto resetAudit(ResetAuditReqDto reqDto, String agToken, String asToken) {
        ResetAuditResDto resDto = new ResetAuditResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        CustomerPremises customerPremises = customerPremisesService.selectByIdForLock(Long.valueOf(reqDto.getId()));
        if (Objects.isNull(customerPremises)) {
            resDto.setResultMsg("报备记录错误,请刷新后重试!");
            return resDto;
        }

        String oldCustomerStatus = customerPremises.getCustomerStatus();
        String newCustomerStatus = reqDto.getCustomerStatus();
        if(CustomerStatusEnum.report_invalid.getNo().equals(newCustomerStatus)
                || CustomerStatusEnum.visit_invalid.getNo().equals(newCustomerStatus)){
            newCustomerStatus = CustomerStatusEnum.no_valid.getNo();
        }

        String oldConfirmStatus = customerPremises.getConfirmStatus();
        String newConfirmStatus = ConfirmStatusEnum.confirm.getNo();

        CustomerPremisesDto cusPreDto = new CustomerPremisesDto();
        cusPreDto.setId(customerPremises.getId());
        cusPreDto.setCustomerStatus(newCustomerStatus);
        cusPreDto.setAdviserUuid(reqDto.getAdviserUuid());
        if (CustomerStatusEnum.no_valid.getNo().equals(newCustomerStatus)) {
            if(CustomerStatusEnum.report_invalid.getNo().equals(reqDto.getCustomerStatus())){
                cusPreDto.setDisableType(DisableTypeEnum.report_invalid.getNo());
            }else if(CustomerStatusEnum.visit_invalid.getNo().equals(reqDto.getCustomerStatus())){
                cusPreDto.setDisableType(DisableTypeEnum.visit_invalid.getNo());
            }
        }

        // 变更为到访时,重新计算到访保护时间
        if (CustomerStatusEnum.has_visited.getNo().equals(newCustomerStatus)) {
            Date nowTime = new Date();
            Premises premises = premisesService.selectSimpleById(customerPremises.getPremisesId());
            Date visitTime = reqDto.getCreateTime();
            if (Objects.nonNull(visitTime)) {
                nowTime = visitTime;
            }
            cusPreDto.setVisitTime(nowTime);
            // 根据楼盘规则,设置保护时间
            String visitBaohuType = premises.getVisitBaohuType();
            String visitBaohu = premises.getVisitBaohu();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(nowTime);
            if (TimeUnitTypeEnum.DAY.getNo().equals(visitBaohuType)
                    || TimeUnitTypeEnum.HOUR.getNo().equals(visitBaohuType)
                    || TimeUnitTypeEnum.MINUT.getNo().equals(visitBaohuType)) {
                calendar.add(Calendar.MINUTE, Integer.valueOf(visitBaohu));
                cusPreDto.setVisitBaohuTime(calendar.getTime());
            } else if (TimeUnitTypeEnum.NONE.getNo().equals(visitBaohuType)) {
                // 不需要保护,默认为当前时间
                cusPreDto.setVisitBaohuTime(calendar.getTime());
            }
            // 变更置业顾问
            adviserChangeDao.addAdviserChange(Arrays.asList(customerPremises), reqDto.getAdviserUuid(), reqDto.getUserId());
        }
        customerPremisesService.update(cusPreDto);

        // 添加跟进
        PartnerInfo pi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
        List<AffixDto> affixList = reqDto.getAffixList();
        String operFollowRemark = "【重置报备状态】";
        String oldDesc = CustomerStatusEnum.getDescByNo(oldCustomerStatus);
        String newDesc = CustomerStatusEnum.getDescByNo(newCustomerStatus);
        operFollowRemark += oldDesc + "->" + newDesc + "。";
        operFollowRemark += reqDto.getRemark();
        Map<String, String> statusMap = new HashMap<>();
        statusMap.put("oldCustomerStatus", oldCustomerStatus);
        statusMap.put("newCustomerStatus", newCustomerStatus);
        statusMap.put("oldConfirmStatus", oldConfirmStatus);
        statusMap.put("newConfirmStatus", newConfirmStatus);
        reportCommonService.setAuditFollow(pi, Long.valueOf(reqDto.getId()), statusMap, cusPreDto.getDisableType(), operFollowRemark, affixList, OperationTypeEnum.OPERATIONTYPE_3.getCode());

        // 推送消息
        WxMsgCommonDto wxMsgCommonDto = new WxMsgCommonDto();
        wxMsgCommonDto.setDomain(reqDto.getDomain());
        wxMsgCommonDto.setCompanyUuid(reqDto.getCompanyUuid());
        wxMsgCommonDto.setRemark(reqDto.getRemark());
        reportCommonService.sendAuditWxMsg(customerPremises, statusMap, wxMsgCommonDto, agToken, asToken);

        // 同步到M2
        if (CustomerStatusEnum.has_visited.getNo().equals(newCustomerStatus)) {
            long companyId = pi.getHigherid();
            String merchantCode = companyService.isDevBindM2(String.valueOf(companyId), CompanyTypeEnum.COMPANY_TYPE_VALUE_2.getCode());
            logger.info("audit report service ==> resetAudit --> companyId: {}, mercahntCode: {}", companyId, merchantCode);
            if (StringUtils.isNotBlank(merchantCode)) {
                Premises premises = premisesService.selectSimpleById(customerPremises.getPremisesId());
                if (StringUtils.isNotBlank(premises.getProjectCodeM2())) {
                    reportCommonService.customerToM2(customerPremises, m2ApiConfig.getM2RequestUrl(),merchantCode);
                }
            }
            // 发送到访短信
            reportCommonService.sendAuditCPSms(pi, customerPremises);
        }

        // 同步V10
        SyncReportStatusToV10Dto toV10Dto = new SyncReportStatusToV10Dto();
        toV10Dto.setReportId(customerPremises.getId());
        toV10Dto.setCompanyUuid(reqDto.getCompanyUuid());
        toV10Dto.setRemark(reqDto.getRemark());
        toV10Dto.setOperFollowRemark(operFollowRemark);
        reportCommonService.syncResetReportStatusToV10(OperationTypeEnum.OPERATIONTYPE_3.getCode(), toV10Dto, statusMap, affixList);
        resDto.setResult(ResultEnum.SUCCESS.getNo());
        return resDto;
    }

    @Override
    @Transactional
    public ChangeCPConfirmResDto changeCPConfirm(ChangeCPConfirmReqDto reqDto, String agencyAccessToken, String assistantAccessToken) {
        ChangeCPConfirmResDto resDto = new ChangeCPConfirmResDto();
        String domain = reqDto.getDomain();
        String companyUuid = reqDto.getCompanyUuid();
        if (StringUtils.isEmpty(domain) && StringUtils.isEmpty(companyUuid)) {
            resDto.setResult(ResultEnum.FAIL.getNo());
            resDto.setResultMsg("获取公司信息失败!");
            return resDto;
        }

        /*
         * 更新交易状态
         * 重复操作校验
         * 交易流程 逆向操作检查
         */
        CustomerPremises cusPre = customerPremisesService.selectByIdForLock(Long.valueOf(reqDto.getId()));
        if (cusPre.getConfirmStatus().equals(reqDto.getConfirmStatus())) {
            resDto.setResultMsg("操作重复，请刷新之后进行操作！");
            return resDto;
        }
        checkCPConfirmStatus(cusPre.getConfirmStatus(), reqDto.getConfirmStatus());
        String oldConfirmStatus = cusPre.getConfirmStatus();
        String newConfirmStatus = reqDto.getConfirmStatus();
        String oldCustomerStatus = cusPre.getCustomerStatus();
        String newCustomerStatus = cusPre.getCustomerStatus();

        CustomerPremisesDto cpDto = new CustomerPremisesDto();
        BeanUtils.copyProperties(cusPre, cpDto);
        cpDto.setConfirmStatus(newConfirmStatus);
        if (StringUtils.isNotEmpty(reqDto.getBuildingName())) {
            cpDto.setBuildingName(reqDto.getBuildingName());
        }
        if (StringUtils.isNotEmpty(reqDto.getRoomName())) {
            cpDto.setRoomName(reqDto.getRoomName());
        }
        if (StringUtils.isNotEmpty(reqDto.getValuationArea())) {
            cpDto.setValuationArea(new BigDecimal(reqDto.getValuationArea()));
        }
        if (StringUtils.isNotEmpty(reqDto.getDealAmount())) {
            cpDto.setDealAmount(new BigDecimal(reqDto.getDealAmount()));
        }
        if (StringUtils.isNotEmpty(reqDto.getSignatureAmount())) {
            cpDto.setSignatureAmount(new BigDecimal(reqDto.getSignatureAmount()));
        }

        Date nowTime = Calendar.getInstance().getTime();

        String weappMsgFailure = "";
        if (ConfirmStatusEnum.sign_fail.getNo().equals(reqDto.getConfirmStatus())) {
            ConfirmStatusEnum statusEnum = ConfirmStatusEnum.getByNo(cusPre.getConfirmStatus());
            cpDto.setDealFailTime(nowTime);
            switch (statusEnum) {
                case payDeposit:
                    cpDto.setDisableType(DisableTypeEnum.PAYDEPOSIT_FAILD.getNo());
                    weappMsgFailure = "退认筹";
                    break;
                case subscribe:
                    cpDto.setDisableType(DisableTypeEnum.SUBSCRIBE_FAILD.getNo());
                    weappMsgFailure = "退认购";
                    break;
                case sign:
                    cpDto.setDisableType(DisableTypeEnum.SIGN_FAILD.getNo());
                    weappMsgFailure = "签约退房";
                    break;
                default:
                    break;
            }
        } else if (!ConfirmStatusEnum.sign_fail.getNo().equals(newConfirmStatus)) {
            ConfirmStatusEnum statusEnum = ConfirmStatusEnum.getByNo(newConfirmStatus);
            switch (statusEnum) {
                case payDeposit:
                    cpDto.setPayDepositTime(nowTime);
                    break;
                case subscribe:
                    cpDto.setSubscribeTime(nowTime);
                    break;
                case sign:
                    cpDto.setSignTime(nowTime);
                    break;
                default:
                    break;
            }
            // 隐号报备审核、到访审核校验是否需要补全手机号
            if (cusPre.getMobile().indexOf(StringConstant.THREE_STAR) >= 0) {
                Premises premises = premisesService.selectSimpleById(cusPre.getPremisesId());
                Boolean flag = cpService.checkCompletePhone(premises, cusPre, newConfirmStatus);
                // 非设置无效操作,校验隐号补全
                if (!flag.booleanValue()) {
                    resDto.setResult(ResultEnum.FAIL.getNo());
                    resDto.setResultMsg("请先补全号码再进行交易操作!");
                    return resDto;
                }
            }
        }

        /*
         * 交易状态变更,判断是否直签
         * 原交易状态待确认,并且新交易状态为签约
         */
        if (ConfirmStatusEnum.confirm.getNo().equals(oldConfirmStatus)
                && ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)) {
            //1: 代表直签
            cpDto.setDirectSign("1");
        }
        if (customerPremisesService.update(cpDto) <= 0) {
            resDto.setResultMsg("更新审核数据失败!");
            return resDto;
        }

        /*
         * 插入跟进
         * 跟进描述
         * 交易状态变更
         */
        PartnerInfo pi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
        List<AffixDto> affixList = reqDto.getAffixList();
        String operFollowRemark = "【" + ConfirmStatusEnum.getDescByNo(newConfirmStatus) + "】" + reqDto.getRemark();
        if (ConfirmStatusEnum.sign_fail.getNo().equals(cpDto.getConfirmStatus())) {
            operFollowRemark = "【" + DisableTypeEnum.getDescByNo(cpDto.getDisableType()) + "】" + reqDto.getRemark();
        }
        Map<String, String> statusMap = new HashMap<>();
        statusMap.put("oldCustomerStatus", oldCustomerStatus);
        statusMap.put("newCustomerStatus", newCustomerStatus);
        statusMap.put("oldConfirmStatus", oldConfirmStatus);
        statusMap.put("newConfirmStatus", newConfirmStatus);
        // 添加跟进
        reportCommonService.setAuditFollow(pi, Long.valueOf(reqDto.getId()), statusMap, cpDto.getDisableType(), operFollowRemark, affixList, OperationTypeEnum.OPERATIONTYPE_2.getCode());

        // 设置佣金
        cpReportService.operateCommission(reqDto.getConfirmStatus(), cpDto, reqDto.getRemark(), pi, Long.valueOf(reqDto.getId()));

        resDto.setResult(ResultEnum.SUCCESS.getNo());
        resDto.setResultMsg("交易状态变更成功!");

        // 根据域名或者公司uuid查询开发商
        CompanyDto cDto = new CompanyDto();
        cDto.setDomain(domain);
        cDto.setStatus(CheckStatusEnum.SUCCESS.getNo());
        cDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
        cDto.setCompanyUuid(companyUuid);
        Company company = companyService.selectByDto(cDto);

        if (null == company) {
            //此处为商户不存在
            resDto.setResult(ResultEnum.FAIL.getNo());
            resDto.setResultMsg("未获取到开发商信息!");
            return resDto;
        }
        Long companyId = company.getId();
        if (companyId == null) {
            return resDto;
        }

        if (ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)) {
            reportCommonService.sendSignCPSms(pi, cusPre);
            // 判断是否万豪签约,是的话推送签约记录至财务系统
            if(CompanyEnum.WZWH.getCode().equals(company.getCompanyUuid())
                || CompanyEnum.TEST.getCode().equals(company.getCompanyUuid())){
                List<Long> reportIds = Arrays.asList(cusPre.getId());
                whReportService.sendWHSyncReport(reportIds);
            }
        }

        //签约成功,发送短信
        WxMsgCommonDto wxMsgCommonDto = new WxMsgCommonDto();
        wxMsgCommonDto.setDomain(reqDto.getDomain());
        wxMsgCommonDto.setCompanyUuid(reqDto.getCompanyUuid());
        wxMsgCommonDto.setCompanyName(company.getCompanyName());
        wxMsgCommonDto.setRemark(reqDto.getRemark());
        wxMsgCommonDto.setWeappMsgFailure(weappMsgFailure);
        reportCommonService.sendConfirmWxMsg(cusPre, statusMap, wxMsgCommonDto, agencyAccessToken, assistantAccessToken);

        /*
         * 与v10同步判断
         */
        SyncReportStatusToV10Dto toV10Dto = new SyncReportStatusToV10Dto();
        toV10Dto.setReportId(cusPre.getId());
        toV10Dto.setCompanyUuid(reqDto.getCompanyUuid());
        toV10Dto.setBuildingName(reqDto.getBuildingName());
        toV10Dto.setRoomName(reqDto.getRoomName());
        toV10Dto.setValuationArea(reqDto.getValuationArea());
        toV10Dto.setDealAmount(reqDto.getDealAmount());
        toV10Dto.setSignatureAmount(reqDto.getSignatureAmount());
        toV10Dto.setRemark(reqDto.getRemark());
        toV10Dto.setOperFollowRemark(operFollowRemark);
        toV10Dto.setDealClientName(cusPre.getDealClientName() == null ? cusPre.getName() : cusPre.getDealClientName());
        if(StringUtils.isNotEmpty(cusPre.getAdviserUuid())){
            EstateAdviser entity = new EstateAdviser();
            entity.setAdviserUuid(cusPre.getAdviserUuid());
            EstateAdviser adviser =  estateAdviserService.selectOne(entity);
            if(adviser != null) {
            	toV10Dto.setAdviserName(adviser.getName());
                toV10Dto.setAdviserPhone(adviser.getPhone());
            }
        }
        reportCommonService.syncReportStatusToV10(OperationTypeEnum.OPERATIONTYPE_2.getCode(), toV10Dto, statusMap, affixList);

        return resDto;
    }

    @Override
    public ResetConfirmResDto resetConfirm(ResetConfirmReqDto reqDto, String agToken, String asToken) {
        ResetConfirmResDto resDto = new ResetConfirmResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        CustomerPremises customerPremises = customerPremisesService.selectByIdForLock(Long.valueOf(reqDto.getId()));
        if (Objects.isNull(customerPremises)) {
            resDto.setResultMsg("报备记录错误,请刷新后重试!");
            return resDto;
        }

        CompanyDto cDto = new CompanyDto();
        cDto.setDomain(reqDto.getDomain());
        cDto.setStatus(CheckStatusEnum.SUCCESS.getNo());
        cDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
        cDto.setCompanyUuid(reqDto.getCompanyUuid());
        Company company = companyService.selectByDto(cDto);

        String oldCustomerStatus = customerPremises.getCustomerStatus();
        String newCustomerStatus = customerPremises.getCustomerStatus();
        String oldConfirmStatus = customerPremises.getConfirmStatus();
        String newConfirmStatus = reqDto.getConfirmStatus();
        CustomerPremisesDto cusPreDto = new CustomerPremisesDto();
        cusPreDto.setId(customerPremises.getId());
        cusPreDto.setBuildingName(customerPremises.getBuildingName());
        cusPreDto.setRoomName(customerPremises.getRoomName());
        cusPreDto.setValuationArea(customerPremises.getValuationArea());
        cusPreDto.setSignatureAmount(customerPremises.getSignatureAmount());
        cusPreDto.setDealAmount(customerPremises.getDealAmount());

        if(ConfirmStatusEnum.confirm.getNo().equals(newConfirmStatus)
                || ConfirmStatusEnum.payDeposit.getNo().equals(newConfirmStatus)
                || (ConfirmStatusEnum.payDeposit.getNo().equals(oldConfirmStatus)
                && ConfirmStatusEnum.sign_fail.getNo().equals(newConfirmStatus))){
            // 待定、认筹、退认筹: 清空所有交易相关信息
            cusPreDto.setBuildingName(null);
            cusPreDto.setRoomName(null);
            cusPreDto.setValuationArea(null);
            cusPreDto.setSignatureAmount(null);
            cusPreDto.setDealAmount(null);
            cusPreDto.setSubscribeTime(null);
            cusPreDto.setSignTime(null);
        }else if(ConfirmStatusEnum.subscribe.getNo().equals(newConfirmStatus)
                || (ConfirmStatusEnum.subscribe.getNo().equals(oldConfirmStatus)
                && ConfirmStatusEnum.sign_fail.getNo().equals(newConfirmStatus))){
            // 认购、退认购: 清空签约相关面积及金额
            cusPreDto.setValuationArea(null);
            cusPreDto.setDealAmount(null);
            cusPreDto.setSignTime(null);
            // 认购时,设置楼栋、房号、签约金额
            if(ConfirmStatusEnum.subscribe.getNo().equals(newConfirmStatus)){
                cusPreDto.setBuildingName(reqDto.getBuildingName());
                cusPreDto.setRoomName(reqDto.getRoomName());
                if (StringUtils.isNotEmpty(reqDto.getSignatureAmount())) {
                    cusPreDto.setSignatureAmount(new BigDecimal(reqDto.getSignatureAmount()));
                }
            }
        }else if(ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)){
            cusPreDto.setBuildingName(reqDto.getBuildingName());
            cusPreDto.setRoomName(reqDto.getRoomName());
            if (StringUtils.isNotBlank(reqDto.getValuationArea())) {
                cusPreDto.setValuationArea(new BigDecimal(reqDto.getValuationArea()));
            }
            if (StringUtils.isNotBlank(reqDto.getDealAmount())) {
                cusPreDto.setDealAmount(new BigDecimal(reqDto.getDealAmount()));
            }

            // 判断是否万豪签约,是的话推送签约记录至财务系统
            if(CompanyEnum.WZWH.getCode().equals(company.getCompanyUuid())
                || CompanyEnum.TEST.getCode().equals(company.getCompanyUuid())){
                List<Long> reportIds = Arrays.asList(customerPremises.getId());
                whReportService.sendWHSyncReport(reportIds);
            }

        }
        if(ConfirmStatusEnum.PAYDEPOSIT_FAILD.getNo().equals(newConfirmStatus)
                || ConfirmStatusEnum.SUBSCRIBE_FAILD.getNo().equals(newConfirmStatus)
                || ConfirmStatusEnum.SIGN_FAILD.getNo().equals(newConfirmStatus)){
            newConfirmStatus = ConfirmStatusEnum.sign_fail.getNo();
        }
        cusPreDto.setConfirmStatus(newConfirmStatus);

        String weappMsgFailure = "";
        Date nowTime = new Date();
        cusPreDto.setDisableType(null);
        if (ConfirmStatusEnum.sign_fail.getNo().equals(newConfirmStatus)) {
            ConfirmStatusEnum statusEnum = ConfirmStatusEnum.getByNo(oldConfirmStatus);
            cusPreDto.setDealFailTime(nowTime);
            switch (statusEnum) {
                case payDeposit:
                    cusPreDto.setDisableType(DisableTypeEnum.PAYDEPOSIT_FAILD.getNo());
                    weappMsgFailure = "退认筹";
                    break;
                case subscribe:
                    cusPreDto.setDisableType(DisableTypeEnum.SUBSCRIBE_FAILD.getNo());
                    weappMsgFailure = "退认购";
                    break;
                case sign:
                    cusPreDto.setDisableType(DisableTypeEnum.SIGN_FAILD.getNo());
                    weappMsgFailure = "签约退房";
                    break;
                default:
                    break;
            }
        } else if (!ConfirmStatusEnum.sign_fail.getNo().equals(newConfirmStatus)) {
            ConfirmStatusEnum statusEnum = ConfirmStatusEnum.getByNo(newConfirmStatus);
            switch (statusEnum) {
                case payDeposit:
                    cusPreDto.setPayDepositTime(nowTime);
                    break;
                case subscribe:
                    cusPreDto.setSubscribeTime(nowTime);
                    break;
                case sign:
                    cusPreDto.setSignTime(nowTime);
                    break;
                default:
                    break;
            }
        }
        customerPremisesService.resetConfirm(cusPreDto);

        // 添加跟进
        PartnerInfo pi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
        List<AffixDto> affixList = reqDto.getAffixList();
        String operFollowRemark = "【重置交易状态】";
        String oldDesc = ConfirmStatusEnum.getDescByNo(oldConfirmStatus);
        String newDesc = ConfirmStatusEnum.getDescByNo(newConfirmStatus);
        operFollowRemark += oldDesc + "->" + newDesc + "。";
        operFollowRemark += reqDto.getRemark();
        Map<String, String> statusMap = new HashMap<>();
        statusMap.put("oldCustomerStatus", oldCustomerStatus);
        statusMap.put("newCustomerStatus", newCustomerStatus);
        statusMap.put("oldConfirmStatus", oldConfirmStatus);
        statusMap.put("newConfirmStatus", newConfirmStatus);
        reportCommonService.setAuditFollow(pi, Long.valueOf(reqDto.getId()), statusMap, cusPreDto.getDisableType(), operFollowRemark, affixList, OperationTypeEnum.OPERATIONTYPE_2.getCode());

        // 推送消息
        WxMsgCommonDto wxMsgCommonDto = new WxMsgCommonDto();
        wxMsgCommonDto.setDomain(reqDto.getDomain());
        wxMsgCommonDto.setCompanyUuid(reqDto.getCompanyUuid());
        wxMsgCommonDto.setCompanyName(company.getCompanyName());
        wxMsgCommonDto.setRemark(reqDto.getRemark());
        wxMsgCommonDto.setWeappMsgFailure(weappMsgFailure);
        reportCommonService.sendConfirmWxMsg(customerPremises, statusMap, wxMsgCommonDto, agToken, asToken);

        // 同步V10
        SyncReportStatusToV10Dto toV10Dto = new SyncReportStatusToV10Dto();
        toV10Dto.setReportId(customerPremises.getId());
        toV10Dto.setCompanyUuid(reqDto.getCompanyUuid());
        toV10Dto.setBuildingName(cusPreDto.getBuildingName());
        toV10Dto.setRoomName(cusPreDto.getRoomName());
        toV10Dto.setValuationArea(String.valueOf(cusPreDto.getValuationArea()));
        toV10Dto.setDealAmount(String.valueOf(cusPreDto.getDealAmount()));
        toV10Dto.setSignatureAmount(String.valueOf(cusPreDto.getSignatureAmount()));
        toV10Dto.setRemark(cusPreDto.getRemark());
        toV10Dto.setOperFollowRemark(operFollowRemark);
        reportCommonService.syncResetReportStatusToV10(OperationTypeEnum.OPERATIONTYPE_2.getCode(), toV10Dto, statusMap, affixList);
        resDto.setResult(ResultEnum.SUCCESS.getNo());
        return resDto;
    }

    @Override
    public ChangeCPMortgageResDto changeCPMortgage(ChangeCPMortgageReqDto reqDto) {
        ChangeCPMortgageResDto resDto = new ChangeCPMortgageResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        try {
            Long id = Long.valueOf(reqDto.getId());
            String mortgageStatus = reqDto.getMortgageStatus();
            String remark = reqDto.getRemark();

            CustomerPremises cusPre = customerPremisesService.selectById(id);
            if (null == cusPre) {
                resDto.setResultMsg("报备记录错误,无法变更按揭状态!");
                return resDto;
            }
            if (mortgageStatus.equals(cusPre.getMortgageStatus())) {
                resDto.setResultMsg("不可重复操作，请刷新后重试!");
                return resDto;
            }

            CustomerPremisesDto cusPreDto = new CustomerPremisesDto();
            cusPreDto.setId(id);
            cusPreDto.setMortgageStatus(mortgageStatus);
            customerPremisesService.update(cusPreDto);

            // 新增跟进信息
            PartnerInfo pi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
            FollowUpListDto follow = new FollowUpListDto();
            follow.setStaffId(pi.getId());
            follow.setCustomerPremisesId(id);
            follow.setOldConfirmStatus(cusPre.getConfirmStatus());
            follow.setNewConfirmStatus(cusPre.getConfirmStatus());
            follow.setOldCustomerStatus(cusPre.getCustomerStatus());
            follow.setNewCustomerStatus(cusPre.getCustomerStatus());
            follow.setRemark("【变更按揭状态】" + remark);
            follow.setFollowType(FollowTypeEnum.DEVELOPERS.getNo());
            followUpListService.create(follow);
            resDto.setResult(ResultEnum.SUCCESS.getNo());
            resDto.setResultMsg("按揭状态变更成功!");
        } catch (Exception ex) {
            logger.error("按揭状态变更失败: {}", ex);
            resDto.setResultMsg("按揭状态变更失败: " + ex.getMessage());
        }
        return resDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AuditCPAppealResDto auditCPAppeal(AuditCPAppealReqDto reqDto) {
        if (StringUtils.isBlank(reqDto.getId())) {
            throw new TServerException("报备ID不能为空！");
        }
        if (StringUtils.isBlank(reqDto.getProcessStatus())) {
            throw new TServerException("处理状态不能为空！");
        }
        AuditCPAppealResDto resDto = new AuditCPAppealResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        try {
            CustomerPremises cusPre = customerPremisesService.selectById(Long.valueOf(reqDto.getId()));
            if (null == cusPre) {
                resDto.setResultMsg(("报备记录无效,无法进行申诉审核!"));
                return resDto;
            }
            if (!CustomerStatusEnum.normal.getNo().equals(cusPre.getCustomerStatus())) {
                resDto.setResultMsg(("报备非待确认状态,不能处理!"));
                return resDto;
            }
            //申诉次数超过1次,直接置为失败
            Long complaintsNumber = cusPre.getComplaintsNumber();
            if (complaintsNumber.longValue() > 1) {
                CustomerPremisesDto cpDto = new CustomerPremisesDto();
                cpDto.setId(cusPre.getId());
                cpDto.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
                customerPremisesService.update(cpDto);
                resDto.setResultMsg(("申诉超过1次,此记录无需审核!"));
                return resDto;
            }

            //通过楼盘查询到对应的案场人员以及案场人员对应的公司
            Premises premises = premisesService.selectSimpleById(cusPre.getPremisesId());
            if (null == premises || DelFlagEnum.DEL.getNo().equals(premises.getDelFlag())) {
                resDto.setResultMsg(("楼盘无效,此记录无法审核!"));
                return resDto;
            }

            String oldConfirmStatus = cusPre.getConfirmStatus();
            String oldCustomerStatus = cusPre.getCustomerStatus();

            CustomerPremisesDto cpDto = new CustomerPremisesDto();
            BeanUtils.copyProperties(cusPre, cpDto);
            cpDto.setProcessStatus(reqDto.getProcessStatus());
            cpDto.setProcessRemark(reqDto.getRemark());
            /**
             * 申诉状态
             * 1、转为报备有效：更新报备状态为报备有效
             * 2、不通过：发起申诉次数+1
             */
            //微信小程序所需参数
            Map<String, String> weappAgencyMsgMap = new HashMap<>();
            weappAgencyMsgMap.put("id", String.valueOf(cusPre.getId()));
            weappAgencyMsgMap.put("staffId", String.valueOf(cusPre.getStaffId()));
            weappAgencyMsgMap.put("premisesId", String.valueOf(cusPre.getPremisesId()));
            weappAgencyMsgMap.put("customerName", cusPre.getName());
            weappAgencyMsgMap.put("customerPhone", cusPre.getMobile());
            weappAgencyMsgMap.put("createTime", DateUtils.DateToString(cusPre.getCreateTime(), DateStyle.YYYY_MM_DD_HH_MM_SS));
            weappAgencyMsgMap.put("hopeVisitTime", Objects.isNull(cusPre.getHopeVisitTime())?"":DateUtils.DateToString(cusPre.getHopeVisitTime(), DateStyle.YYYY_MM_DD_HH_MM_SS));
            weappAgencyMsgMap.put("changeTime", DateUtils.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
            weappAgencyMsgMap.put("remark", reqDto.getRemark());
            weappAgencyMsgMap.put("companyUuid", reqDto.getCompanyUuid());
            if (ProcessStatusEnum.toEffectiveReporting.getNo().equals(reqDto.getProcessStatus())) {
                //通过，改为未到访
                cpDto.setCustomerStatus(CustomerStatusEnum.not_visited.getNo());
                weappAgencyMsgMap.put("changeStatus", CustomerStatusEnum.not_visited.getDes());
                //报备审核成功小程序消息通知
                weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_AUDIT_SUCCESS.getNo());
            } else if (ProcessStatusEnum.fail.getNo().equals(reqDto.getProcessStatus())) {
                //不通过
                cpDto.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
                weappAgencyMsgMap.put("failureDesc", "有一条报备申诉被驳回，您无法再发起申诉");
                weappAgencyMsgMap.put("changeStatus", CustomerStatusEnum.no_valid.getDes());
                //报备审核成功小程序消息通知
                weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_AUDIT_FAILURE.getNo());
            }
            cpDto.setComplaintsNumber(Long.parseLong("2"));
            Calendar visitProtectCalendar = customerPremisesService.getVisitProtectCalendar(premises.getId(), premises.getVisitProtect());
            cpDto.setVisitProtectTime(visitProtectCalendar.getTime());
            cpDto.setId(cusPre.getId());
            if (customerPremisesService.update(cpDto) > 0) {
                PartnerInfo pi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
                // 新增跟进信息
                FollowUpListDto follow = new FollowUpListDto();
                follow.setStaffId(pi.getId());
                follow.setCustomerPremisesId(Long.valueOf(reqDto.getId()));
                follow.setOldCustomerStatus(oldCustomerStatus);
                String remark = reqDto.getRemark() != null ? reqDto.getRemark() : "";
                if (ProcessStatusEnum.toEffectiveReporting.getNo().equals(reqDto.getProcessStatus())) {
                    follow.setNewCustomerStatus(CustomerStatusEnum.not_visited.getNo());
                    follow.setRemark("【接受申诉】" + remark);
                    follow.setFollowUpType(FollowUpEnum.status_transfer.getNo());
                } else if (ProcessStatusEnum.fail.getNo().equals(reqDto.getProcessStatus())) {
                    follow.setNewCustomerStatus(CustomerStatusEnum.no_valid.getNo());
                    follow.setRemark("【拒绝申诉】" + remark);
                    follow.setFollowUpType(FollowUpEnum.status_transfer.getNo());
                }

                follow.setOldConfirmStatus(oldConfirmStatus);
                follow.setNewConfirmStatus(oldConfirmStatus);
                follow.setFollowType(FollowTypeEnum.CHANNEL.getNo());
                followUpListService.create(follow);
                resDto.setResult(ResultEnum.SUCCESS.getNo());
                resDto.setResultMsg("申诉审核成功!");
            } else {
                resDto.setResultMsg("申诉审核失败!");
            }
        } catch (Exception ex) {
            logger.error("申诉审核失败: {}", ex);
            resDto.setResultMsg("申诉审核失败: " + ex.getMessage());
        }
        return resDto;
    }

    /**
     * 检查 报备审核状态
     *
     * @return
     */
    private boolean checkCPAuditStatus(String oldStatus, String nowStatus) {
        // 无效 --> 到访,未到访
        if (CustomerStatusEnum.no_valid.getNo().equals(oldStatus) &&
                (CustomerStatusEnum.has_visited.getNo().equals(nowStatus) || CustomerStatusEnum.not_visited.getNo().equals(nowStatus))) {
            throw new TServerException("该报备已无效，请刷新后操作");
        }
        //已到访 --> 未到访,无效
        if (CustomerStatusEnum.has_visited.getNo().equals(oldStatus) &&
                (CustomerStatusEnum.not_visited.getNo().equals(nowStatus) || CustomerStatusEnum.no_valid.getNo().equals(nowStatus))) {
            throw new TServerException("已到访不能设为未到访，请刷新后操作");
        }
        return true;
    }

    /**
     * 检查 报备交易状态
     *
     * @param oldStatus
     * @param nowStatus
     * @return
     */
    private boolean checkCPConfirmStatus(String oldStatus, String nowStatus) {
        //认购 --> 认筹
        if (ConfirmStatusEnum.subscribe.getNo().equals(oldStatus) && ConfirmStatusEnum.payDeposit.getNo().equals(nowStatus)) {
            throw new TServerException("该报备已认购，请刷新后操作");
        }
        //签约  --> 认购， 认筹，签约失败
        if (ConfirmStatusEnum.sign.getNo().equals(oldStatus) &&
                (ConfirmStatusEnum.subscribe.getNo().equals(nowStatus)
                        || ConfirmStatusEnum.payDeposit.getNo().equals(nowStatus)
                        /*|| ConfirmStatusEnum.sign_fail.getNo().equals(nowStatus)*/)) {
            throw new TServerException("该报备已签约，请刷新后操作");
        }
        //签约失败 --> 认购，认筹，签约
        if (ConfirmStatusEnum.sign_fail.getNo().equals(oldStatus) &&
                (ConfirmStatusEnum.subscribe.getNo().equals(nowStatus)
                        || ConfirmStatusEnum.payDeposit.getNo().equals(nowStatus)
                        || ConfirmStatusEnum.sign.getNo().equals(nowStatus))) {
            throw new TServerException("该报备已签约失败，请刷新后操作");
        }
        return true;
    }

    @Override
    public ExchangeHousesResDto exchangeHousesCPConfirm(ExchangeHousesCPConfirmReqDto reqDto, String agencyAccessToken, String assistantAccessToken) {
        ExchangeHousesResDto resDto = new ExchangeHousesResDto();
        String companyUuid = reqDto.getCompanyUuid();
        if (StringUtils.isEmpty(companyUuid)) {
            resDto.setResult(ResultEnum.FAIL.getNo());
            resDto.setResultMsg("获取公司信息失败!");
            return resDto;
        }

        /*
         * 更新交易状态
         * 重复操作校验
         * 交易流程 逆向操作检查
         */
        CustomerPremises cusPre = customerPremisesService.selectByIdForLock(Long.valueOf(reqDto.getId()));
        if (cusPre.getConfirmStatus().equals(reqDto.getConfirmStatus())) {
            resDto.setResultMsg("操作重复，请刷新之后进行操作！");
            return resDto;
        }
        checkCPConfirmStatus(cusPre.getConfirmStatus(), reqDto.getConfirmStatus());
        String oldConfirmStatus = cusPre.getConfirmStatus();
        String newConfirmStatus = reqDto.getConfirmStatus();
        String oldCustomerStatus = cusPre.getCustomerStatus();
        String newCustomerStatus = cusPre.getCustomerStatus();

        CustomerPremisesDto cpDto = new CustomerPremisesDto();
        BeanUtils.copyProperties(cusPre, cpDto);
        cpDto.setConfirmStatus(newConfirmStatus);
        if (StringUtils.isNotEmpty(reqDto.getBuildingName())) {
            cpDto.setBuildingName(reqDto.getBuildingName());
        }
        if (StringUtils.isNotEmpty(reqDto.getRoomName())) {
            cpDto.setRoomName(reqDto.getRoomName());
        }
        if (StringUtils.isNotEmpty(reqDto.getValuationArea())) {
            cpDto.setValuationArea(new BigDecimal(reqDto.getValuationArea()));
        }
        if (StringUtils.isNotEmpty(reqDto.getDealAmount())) {
            cpDto.setDealAmount(new BigDecimal(reqDto.getDealAmount()));
        }
        if (StringUtils.isNotEmpty(reqDto.getSignatureAmount())) {
            cpDto.setSignatureAmount(new BigDecimal(reqDto.getSignatureAmount()));
        }

        Date nowTime = Calendar.getInstance().getTime();

        String weappMsgFailure = "";
        ConfirmStatusEnum statusEnum = ConfirmStatusEnum.getByNo(newConfirmStatus);
        switch (statusEnum) {
            case payDeposit:
                cpDto.setPayDepositTime(nowTime);
                break;
            case subscribe:
                cpDto.setSubscribeTime(nowTime);
                break;
            case sign:
                cpDto.setSignTime(nowTime);
                break;
            default:
                break;
        }

        /*
         * 交易状态变更,判断是否直签
         * 原交易状态待确认,并且新交易状态为签约
         */
        if (ConfirmStatusEnum.confirm.getNo().equals(oldConfirmStatus)
                && ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)) {
            //1: 代表直签
            cpDto.setDirectSign("1");
        }
        if (customerPremisesService.update(cpDto) <= 0) {
            resDto.setResultMsg("更新审核数据失败!");
            return resDto;
        }

        /*
         * 插入跟进
         * 跟进描述
         * 交易状态变更
         */
        PartnerInfo pi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
        List<AffixDto> affixList = reqDto.getAffixList();
        String operFollowRemark = "【换房】" + reqDto.getRemark();
        Map<String, String> statusMap = new HashMap<>();
        statusMap.put("oldCustomerStatus", oldCustomerStatus);
        statusMap.put("newCustomerStatus", newCustomerStatus);
        statusMap.put("oldConfirmStatus", oldConfirmStatus);
        statusMap.put("newConfirmStatus", newConfirmStatus);
        // 添加跟进
        reportCommonService.setAuditFollow(pi, Long.valueOf(reqDto.getId()), statusMap, cpDto.getDisableType(), operFollowRemark, affixList, OperationTypeEnum.OPERATIONTYPE_9.getCode());

        // TODO: 2020/11/30  设置佣金，佣金需要重置
        //cpReportService.operateCommission(reqDto.getConfirmStatus(), cpDto, reqDto.getRemark(), pi, Long.valueOf(reqDto.getId()));

        resDto.setResult(ResultEnum.SUCCESS.getNo());
        resDto.setResultMsg("换房成功!");

        // 根据域名或者公司uuid查询开发商
        CompanyDto cDto = new CompanyDto();
        cDto.setStatus(CheckStatusEnum.SUCCESS.getNo());
        cDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
        cDto.setCompanyUuid(companyUuid);
        Company company = companyService.selectByDto(cDto);

        if (null == company) {
            //此处为商户不存在
            resDto.setResult(ResultEnum.FAIL.getNo());
            resDto.setResultMsg("未获取到开发商信息!");
            return resDto;
        }
        Long companyId = company.getId();
        if (companyId == null) {
            return resDto;
        }

        if (ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)) {
            reportCommonService.sendSignCPSms(pi, cusPre);
            // 判断是否万豪签约,是的话推送签约记录至财务系统
            if(CompanyEnum.WZWH.getCode().equals(company.getCompanyUuid())
                    || CompanyEnum.TEST.getCode().equals(company.getCompanyUuid())){
                List<Long> reportIds = Arrays.asList(cusPre.getId());
                whReportService.sendWHSyncReport(reportIds);
            }
        }

        //签约成功,发送短信
        WxMsgCommonDto wxMsgCommonDto = new WxMsgCommonDto();
        wxMsgCommonDto.setDomain(reqDto.getDomain());
        wxMsgCommonDto.setCompanyUuid(reqDto.getCompanyUuid());
        wxMsgCommonDto.setCompanyName(company.getCompanyName());
        wxMsgCommonDto.setRemark(reqDto.getRemark());
        wxMsgCommonDto.setWeappMsgFailure(weappMsgFailure);
        reportCommonService.sendConfirmWxMsg(cusPre, statusMap, wxMsgCommonDto, agencyAccessToken, assistantAccessToken);

        /*
         * 与v10同步判断
         */
        SyncReportStatusToV10Dto toV10Dto = new SyncReportStatusToV10Dto();
        toV10Dto.setReportId(cusPre.getId());
        toV10Dto.setCompanyUuid(reqDto.getCompanyUuid());
        toV10Dto.setBuildingName(reqDto.getBuildingName());
        toV10Dto.setRoomName(reqDto.getRoomName());
        toV10Dto.setValuationArea(reqDto.getValuationArea());
        toV10Dto.setDealAmount(reqDto.getDealAmount());
        toV10Dto.setSignatureAmount(reqDto.getSignatureAmount());
        toV10Dto.setRemark(reqDto.getRemark());
        toV10Dto.setOperFollowRemark(operFollowRemark);
        toV10Dto.setDealClientName(cusPre.getDealClientName() == null ? cusPre.getName() : cusPre.getDealClientName());
        if(StringUtils.isNotEmpty(cusPre.getAdviserUuid())){
            EstateAdviser entity = new EstateAdviser();
            entity.setAdviserUuid(cusPre.getAdviserUuid());
            EstateAdviser adviser =  estateAdviserService.selectOne(entity);
            if(adviser != null) {
                toV10Dto.setAdviserName(adviser.getName());
                toV10Dto.setAdviserPhone(adviser.getPhone());
            }
        }
        reportCommonService.syncReportStatusToV10(OperationTypeEnum.OPERATIONTYPE_9.getCode(), toV10Dto, statusMap, affixList);

        return resDto;
    }

    @Override
    @Transactional
    public ChangeCPConfirmResDto newChangeCPConfirm(ChangeCPConfirmReqDto reqDto, String agencyAccessToken, String assistantAccessToken) {
        ChangeCPConfirmResDto resDto = new ChangeCPConfirmResDto();
        String domain = reqDto.getDomain();
        String companyUuid = reqDto.getCompanyUuid();
        if (StringUtils.isEmpty(domain) && StringUtils.isEmpty(companyUuid)) {
            resDto.setResult(ResultEnum.FAIL.getNo());
            resDto.setResultMsg("获取公司信息失败!");
            return resDto;
        }

        /*
         * 更新交易状态
         * 重复操作校验
         */
        CustomerPremises cusPre = customerPremisesService.selectByIdForLock(Long.valueOf(reqDto.getId()));
        if (cusPre.getConfirmStatus().equals(reqDto.getConfirmStatus())) {
            resDto.setResultMsg("操作重复，请刷新之后进行操作！");
            return resDto;
        }
        //checkCPConfirmStatus(cusPre.getConfirmStatus(), reqDto.getConfirmStatus());
        String oldConfirmStatus = cusPre.getConfirmStatus();
        String newConfirmStatus = reqDto.getConfirmStatus();
        String oldCustomerStatus = cusPre.getCustomerStatus();
        String newCustomerStatus = cusPre.getCustomerStatus();

        CustomerPremisesDto cpDto = new CustomerPremisesDto();
        BeanUtils.copyProperties(cusPre, cpDto);
        cpDto.setConfirmStatus(newConfirmStatus);
        if (StringUtils.isNotEmpty(reqDto.getBuildingName())) {
            cpDto.setBuildingName(reqDto.getBuildingName());
        }
        if (StringUtils.isNotEmpty(reqDto.getRoomName())) {
            cpDto.setRoomName(reqDto.getRoomName());
        }
        if (StringUtils.isNotEmpty(reqDto.getValuationArea())) {
            cpDto.setValuationArea(new BigDecimal(reqDto.getValuationArea()));
        }
        if (StringUtils.isNotEmpty(reqDto.getDealAmount())) {
            cpDto.setDealAmount(new BigDecimal(reqDto.getDealAmount()));
        }
        if (StringUtils.isNotEmpty(reqDto.getSignatureAmount())) {
            cpDto.setSignatureAmount(new BigDecimal(reqDto.getSignatureAmount()));
        }

        Date nowTime = Calendar.getInstance().getTime();

        String weappMsgFailure = "";
        if (ConfirmStatusEnum.sign_fail.getNo().equals(reqDto.getConfirmStatus())) {
            ConfirmStatusEnum statusEnum = ConfirmStatusEnum.getByNo(cusPre.getConfirmStatus());
            cpDto.setDealFailTime(nowTime);
            switch (statusEnum) {
                case payDeposit:
                    cpDto.setDisableType(DisableTypeEnum.PAYDEPOSIT_FAILD.getNo());
                    weappMsgFailure = "退认筹";
                    break;
                case subscribe:
                    cpDto.setDisableType(DisableTypeEnum.SUBSCRIBE_FAILD.getNo());
                    weappMsgFailure = "退认购";
                    break;
                case sign:
                    cpDto.setDisableType(DisableTypeEnum.SIGN_FAILD.getNo());
                    weappMsgFailure = "签约退房";
                    break;
                default:
                    break;
            }
        } else if (!ConfirmStatusEnum.sign_fail.getNo().equals(newConfirmStatus)) {
            ConfirmStatusEnum statusEnum = ConfirmStatusEnum.getByNo(newConfirmStatus);
            switch (statusEnum) {
                case payDeposit:
                    cpDto.setPayDepositTime(nowTime);
                    break;
                case subscribe:
                    cpDto.setSubscribeTime(nowTime);
                    break;
                case sign:
                    cpDto.setSignTime(nowTime);
                    break;
                default:
                    break;
            }
            // 隐号报备审核、到访审核校验是否需要补全手机号
            if (cusPre.getMobile().indexOf(StringConstant.THREE_STAR) >= 0) {
                Premises premises = premisesService.selectSimpleById(cusPre.getPremisesId());
                Boolean flag = cpService.checkCompletePhone(premises, cusPre, newConfirmStatus);
                // 非设置无效操作,校验隐号补全
                if (!flag.booleanValue()) {
                    resDto.setResult(ResultEnum.FAIL.getNo());
                    resDto.setResultMsg("请先补全号码再进行交易操作!");
                    return resDto;
                }
            }
        }

        /*
         * 交易状态变更,判断是否直签
         * 原交易状态待确认,并且新交易状态为签约
         */
        if (ConfirmStatusEnum.confirm.getNo().equals(oldConfirmStatus)
                && ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)) {
            //1: 代表直签
            cpDto.setDirectSign("1");
        }
        if (customerPremisesService.update(cpDto) <= 0) {
            resDto.setResultMsg("更新审核数据失败!");
            return resDto;
        }

        /*
         * 插入跟进
         * 跟进描述
         * 交易状态变更
         */
        PartnerInfo pi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
        List<AffixDto> affixList = reqDto.getAffixList();
        String operFollowRemark = "【" + ConfirmStatusEnum.getDescByNo(newConfirmStatus) + "】" + reqDto.getRemark();
        if (ConfirmStatusEnum.sign_fail.getNo().equals(cpDto.getConfirmStatus())) {
            operFollowRemark = "【" + DisableTypeEnum.getDescByNo(cpDto.getDisableType()) + "】" + reqDto.getRemark();
        }
        Map<String, String> statusMap = new HashMap<>();
        statusMap.put("oldCustomerStatus", oldCustomerStatus);
        statusMap.put("newCustomerStatus", newCustomerStatus);
        statusMap.put("oldConfirmStatus", oldConfirmStatus);
        statusMap.put("newConfirmStatus", newConfirmStatus);
        // 添加跟进
        reportCommonService.setAuditFollow(pi, Long.valueOf(reqDto.getId()), statusMap, cpDto.getDisableType(), operFollowRemark, affixList, OperationTypeEnum.OPERATIONTYPE_2.getCode());

        // 设置佣金
        cpReportService.operateCommission(reqDto.getConfirmStatus(), cpDto, reqDto.getRemark(), pi, Long.valueOf(reqDto.getId()));

        resDto.setResult(ResultEnum.SUCCESS.getNo());
        resDto.setResultMsg("交易状态变更成功!");

        // 根据域名或者公司uuid查询开发商
        CompanyDto cDto = new CompanyDto();
        cDto.setDomain(domain);
        cDto.setStatus(CheckStatusEnum.SUCCESS.getNo());
        cDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
        cDto.setCompanyUuid(companyUuid);
        Company company = companyService.selectByDto(cDto);

        if (null == company) {
            //此处为商户不存在
            resDto.setResult(ResultEnum.FAIL.getNo());
            resDto.setResultMsg("未获取到开发商信息!");
            return resDto;
        }
        Long companyId = company.getId();
        if (companyId == null) {
            return resDto;
        }

        if (ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)) {
            reportCommonService.sendSignCPSms(pi, cusPre);
            // 判断是否万豪签约,是的话推送签约记录至财务系统
            if(CompanyEnum.WZWH.getCode().equals(company.getCompanyUuid())
                    || CompanyEnum.TEST.getCode().equals(company.getCompanyUuid())){
                List<Long> reportIds = Arrays.asList(cusPre.getId());
                whReportService.sendWHSyncReport(reportIds);
            }
        }

        //签约成功,发送短信
        WxMsgCommonDto wxMsgCommonDto = new WxMsgCommonDto();
        wxMsgCommonDto.setDomain(reqDto.getDomain());
        wxMsgCommonDto.setCompanyUuid(reqDto.getCompanyUuid());
        wxMsgCommonDto.setCompanyName(company.getCompanyName());
        wxMsgCommonDto.setRemark(reqDto.getRemark());
        wxMsgCommonDto.setWeappMsgFailure(weappMsgFailure);
        reportCommonService.sendConfirmWxMsg(cusPre, statusMap, wxMsgCommonDto, agencyAccessToken, assistantAccessToken);

        /*
         * 与v10同步判断
         */
        SyncReportStatusToV10Dto toV10Dto = new SyncReportStatusToV10Dto();
        toV10Dto.setReportId(cusPre.getId());
        toV10Dto.setCompanyUuid(reqDto.getCompanyUuid());
        toV10Dto.setBuildingName(reqDto.getBuildingName());
        toV10Dto.setRoomName(reqDto.getRoomName());
        toV10Dto.setValuationArea(reqDto.getValuationArea());
        toV10Dto.setDealAmount(reqDto.getDealAmount());
        toV10Dto.setSignatureAmount(reqDto.getSignatureAmount());
        toV10Dto.setRemark(reqDto.getRemark());
        toV10Dto.setOperFollowRemark(operFollowRemark);
        toV10Dto.setDealClientName(cusPre.getDealClientName() == null ? cusPre.getName() : cusPre.getDealClientName());
        if(StringUtils.isNotEmpty(cusPre.getAdviserUuid())){
            EstateAdviser entity = new EstateAdviser();
            entity.setAdviserUuid(cusPre.getAdviserUuid());
            EstateAdviser adviser =  estateAdviserService.selectOne(entity);
            if(adviser != null) {
                toV10Dto.setAdviserName(adviser.getName());
                toV10Dto.setAdviserPhone(adviser.getPhone());
            }
        }
        reportCommonService.syncResetReportStatusToV10(OperationTypeEnum.OPERATIONTYPE_2.getCode(), toV10Dto, statusMap, affixList);

        return resDto;
    }
}
